﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon;
using Amazon.SQS;
using Amazon.SQS.Model;
using DevToolBox.Common;
using DevToolBox.Cloud.Common;

namespace DevToolBox.Cloud.Amazon
{
    /// <summary>
    /// Class to encapsulate the interaction with the Amazon 
    /// Simple Queue Service -SQS-
    /// </summary>
    public class AmazonSQSTransaction : IQueueable
    {
        private AmazonSQSConfig config = null;
        private AmazonSQS client = null;
        private string accountNumber = null;
        private string serviceURL = null;
        private int numOfMessagesToRead;

        /// <summary>
        /// Default constructor
        /// </summary>
        public AmazonSQSTransaction(string newServiceURL, string newAccountNumber)
        {
            config = new AmazonSQSConfig();
            config.UseSecureStringForAwsSecretKey = false;
            config.ServiceURL = newServiceURL;
            client = AWSClientFactory.CreateAmazonSQSClient(config);
            accountNumber = newAccountNumber;
            serviceURL = newServiceURL;
            numOfMessagesToRead = ConfigParamReader.GetInt32("AmazonQueueItemsToRead");
        }

        /// <summary>
        /// Method to the dispose the main class object
        /// </summary>
        public void Dispose()
        {
            if (client != null)
            {
                client.Dispose();
            }
        }

        /// <summary>
        /// Method to write an item into the queue
        /// </summary>
        public void Set(object[] keys)
        {
            string deviceReadQueue = Convert.ToString(keys[0]);
            var sendRequest = new SendMessageRequest();
            sendRequest.MessageBody = Convert.ToString(keys[1]);
            sendRequest.QueueUrl = serviceURL + "/" + accountNumber + "/" + deviceReadQueue;
            client.SendMessage(sendRequest);
        }

        /// <summary>
        /// Get the last added item from the queue
        /// </summary>
        /// <param name="key">Key to construct the Amazon SQS URL</param>
        /// <returns>Last added item</returns>
        public object Get(object key)
        {
            string deviceReadQueue = Convert.ToString(key);
            var receiveRequest = new ReceiveMessageRequest();
            receiveRequest.VisibilityTimeout = 5;
            receiveRequest.QueueUrl = serviceURL + "/" + accountNumber + "/" + deviceReadQueue;

            //FEB-21-2013: See http://bit.ly/W6cYgH
            receiveRequest.MaxNumberOfMessages = numOfMessagesToRead;

            var receiveResponse = client.ReceiveMessage(receiveRequest);
            if (receiveResponse.ReceiveMessageResult.Message.Count > 0)
            {
                List<object[]> responses = new List<object[]>();
                for (int i = 0; i < receiveResponse.ReceiveMessageResult.Message.Count; i++)
                {
                    Message message = receiveResponse.ReceiveMessageResult.Message[i];
                    object[] objValues = new object[2];
                    objValues[0] = message.Body;
                    objValues[1] = message.ReceiptHandle;
                    responses.Add(objValues);
                }
                return responses;
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Method for deleting one message. The operation is not
        /// in batch because is fast enough
        /// </summary>
        /// <param name="key"></param>
        public void Delete(object[] keys)
        {
            string deleteKey = Convert.ToString(keys[0]);
            var deleteRequest = new DeleteMessageRequest();
            deleteRequest.QueueUrl = serviceURL + "/" + accountNumber + "/" + Convert.ToString(keys[1]);
            deleteRequest.ReceiptHandle = deleteKey;
            client.DeleteMessage(deleteRequest);
        }

        public int GetSize(object[] keys)
        {
            if (keys != null)
            {
                string queueUrl = (string)keys[0];
                var attRequest = new GetQueueAttributesRequest();
                var attributes = new List<string>();
                attributes.Add("ApproximateNumberOfMessages");
                attRequest.AttributeName = attributes;
                attRequest.QueueUrl = queueUrl;
                var attResponse = client.GetQueueAttributes(attRequest);
                if (attResponse != null && attResponse.GetQueueAttributesResult != null)
                {
                    return attResponse.GetQueueAttributesResult.ApproximateNumberOfMessages;
                }
            }
            return SearchConstants.NOT_FOUND;
        }
    }
}